package com.valenx.distributedmulticamerasystem.camera.codec;

import com.valenx.distributedmulticamerasystem.camera.api.CodecListener;
import com.valenx.distributedmulticamerasystem.camera.utils.LogUtil;
import ohos.agp.graphics.Surface;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.media.codec.Codec;
import ohos.media.common.BufferInfo;
import ohos.media.common.Format;

import java.nio.ByteBuffer;

//解码器封装类
public class CodecDecoder {
    private static final int WRITE_BUFFER = 1;
    private static final int STOP_CODEC = 2;
    private final MyEventHandler decoderHandler;
    private Codec decoder;
    private CodecListener codecListener;
    private boolean isOpen = false;
//=============================================================================================================

    //构造器
    private CodecDecoder(Builder builder) {
        initDecoder(builder.format, builder.surface);
        decoderHandler = new MyEventHandler(EventRunner.create(CodecEncoder.class.getSimpleName()));
    }
//=============================================================================================================

    //Builder内部类
    public static class Builder {
        private Format format;
        private Surface surface;

        public Builder() {
        }

        public Builder setSurface(Surface surface) {
            this.surface = surface;
            return this;
        }

        public Builder setFormat(Format format) {
            this.format = format;
            return this;
        }

        public CodecDecoder create() {
            return new CodecDecoder(this);
        }
    }
//=============================================================================================================

    //事件处理器子类
    private class MyEventHandler extends EventHandler {
        MyEventHandler(EventRunner eventRunner) {
            super(eventRunner);
        }
        @Override
        protected void processEvent(InnerEvent event) {
            switch (event.eventId) {
                case WRITE_BUFFER:
                    LogUtil.info("CodecDecoder:", "解码器开始解码");
                    System.out.println("解码器开始解码");
                    if (event.object instanceof byte[]) {
                        byte[] bytes = (byte[]) (event.object);
                        int size = (int) event.param;
                        ByteBuffer byteBuffer = decoder.getAvailableBuffer(100);
                        if (byteBuffer != null) {
                            byteBuffer.clear();
                            byteBuffer.put(bytes);
                            BufferInfo bufferInfo = new BufferInfo();
                            bufferInfo.offset = 0;
                            bufferInfo.size = size;
                            boolean isSuccess = decoder.writeBuffer(byteBuffer, bufferInfo);
                            System.out.println("解码器解码完成");
                            LogUtil.info("CodecDecoder:", "解码器解码完成，结果:" + isSuccess);
                        }
                    }
                    break;
                case STOP_CODEC:
                    LogUtil.info("CodecDecoder:", "停止解码");
                    if (decoder.stop() && decoder.release()) {
                        isOpen = false;
                    }
                    break;
                default:
                    break;
            }
        }
    }
//************************************************************************************************************

    //初始化解码器
    private void initDecoder(Format fmt, Surface surface) {
        LogUtil.info("CodecDecoder:", "初始化解码器");
        decoder = Codec.createDecoder();
        decoder.setVideoSurface(surface);
        decoder.setCodecFormat(fmt);
        decoder.registerCodecListener(
                new Codec.ICodecListener() {
                    @Override
                    public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int tag) {
                        LogUtil.info("CodecDecoder:", "onReadBuffer返回解码后数据");
                        if(codecListener != null){
                            codecListener.onGetEncodedBuffer(byteBuffer, bufferInfo);
                        }
                    }

                    @Override
                    public void onError(int tag, int tag1, int tag2) {
                        LogUtil.info("CodecDecoder:", "解码错误");
                    }
                });
    }
//************************************************************************************************************

    //打开解码器
    public void openDecoder() {
        if (!isOpen) {
            if (decoder.start()) {
                isOpen = true;
            }
        }
    }
//************************************************************************************************************

    //开始解码（开始传入数据）
    public void startDecode(byte[] buffer) {
        if (isOpen) {
            InnerEvent innerEvent = InnerEvent.get(WRITE_BUFFER, buffer.length, buffer);
            decoderHandler.sendEvent(innerEvent, 0, EventHandler.Priority.IMMEDIATE);
        }
    }
//************************************************************************************************************
    //停止解码
    public void stopDecode() {
        if (isOpen) {
            decoderHandler.sendEvent(STOP_CODEC);
        }
    }
//************************************************************************************************************

    //设置接收数据的外部监听器
    public void setDecodeListener(CodecListener listener) {
        codecListener = listener;
    }
}
